#include "CEUtilities.h"

#include "CECamera.h"
#include "CERenderQueue.h"
#include "CEGraphicLayer.h"

#include "CESkybox.h"


//----------------------------------------------------------------------
Skybox::Skybox(const STRING &name,
			   const STRING &cubeTexFilePath,
			   size_t size,
			   BOOL visible)
	: Object(name,
			 Object::sceneRoot,
			 Vector3::ZERO,
			 Radian(0.0f), Radian(0.0f), Radian(0.0f),
			 visible)
{
	m_Material.SetDepthTest(FALSE);
	m_Material.SetDepthWrite(FALSE);
	m_Material.AddTextureLayer();
	m_Material.AddTexture(cubeTexFilePath);

	SetSize(size);

	m_pCamera =	NULL;
}


//----------------------------------------------------------------------
Skybox::~Skybox()
{
}


//----------------------------------------------------------------------
void Skybox::SetSize(int size)
{
	m_iSize = size;

	// +x
	m_Vertex[0].Init(Vector3(m_iSize, m_iSize, m_iSize),	0.f, 0.f);
	m_Vertex[1].Init(Vector3(m_iSize, -m_iSize, -m_iSize),	1.f/6, 1.f);
	m_Vertex[2].Init(Vector3(m_iSize, -m_iSize, m_iSize),	0.f, 1.f);
	m_Vertex[3] = m_Vertex[0];
	m_Vertex[4].Init(Vector3(m_iSize, m_iSize, -m_iSize),	1.f/6, 0.f);
	m_Vertex[5] = m_Vertex[1];

	// -x
	m_Vertex[6].Init(Vector3(-m_iSize, m_iSize, -m_iSize),	1.f/6, 0.f);
	m_Vertex[7].Init(Vector3(-m_iSize, -m_iSize, m_iSize),	2.f/6, 1.f);
	m_Vertex[8].Init(Vector3(-m_iSize, -m_iSize, -m_iSize),	1.f/6, 1.f);
	m_Vertex[9] = m_Vertex[6];
	m_Vertex[10].Init(Vector3(-m_iSize, m_iSize, m_iSize),	2.f/6, 0.f);
	m_Vertex[11] = m_Vertex[7];

	// +y
	m_Vertex[12].Init(Vector3(-m_iSize, m_iSize, -m_iSize),	2.f/6, 0.f);
	m_Vertex[13].Init(Vector3(m_iSize, m_iSize, m_iSize),	3.f/6, 1.f);
	m_Vertex[14].Init(Vector3(-m_iSize, m_iSize, m_iSize),	2.f/6, 1.f);
	m_Vertex[15] = m_Vertex[12];
	m_Vertex[16].Init(Vector3(m_iSize, m_iSize, -m_iSize),	3.f/6, 0.f);
	m_Vertex[17] = m_Vertex[13];
	
	// -y
	m_Vertex[18].Init(Vector3(-m_iSize, -m_iSize, m_iSize),	3.f/6, 0.f);
	m_Vertex[19].Init(Vector3(m_iSize, -m_iSize, -m_iSize),	4.f/6, 1.f);
	m_Vertex[20].Init(Vector3(-m_iSize, -m_iSize, -m_iSize),3.f/6, 1.f);
	m_Vertex[21] = m_Vertex[18];
	m_Vertex[22].Init(Vector3(m_iSize, -m_iSize, m_iSize),	4.f/6, 0.f);
	m_Vertex[23] = m_Vertex[19];

	// +z
	m_Vertex[24].Init(Vector3(-m_iSize, m_iSize, m_iSize),	4.f/6, 0.f);
	m_Vertex[25].Init(Vector3(m_iSize, -m_iSize, m_iSize),	5.f/6, 1.f);
	m_Vertex[26].Init(Vector3(-m_iSize, -m_iSize, m_iSize),	4.f/6, 1.f);
	m_Vertex[27] = m_Vertex[24];
	m_Vertex[28].Init(Vector3(m_iSize, m_iSize, m_iSize),	5.f/6, 0.f);
	m_Vertex[29] = m_Vertex[25];

	// -z
	m_Vertex[30].Init(Vector3(m_iSize, m_iSize, -m_iSize),	5.f/6, 0.f);
	m_Vertex[31].Init(Vector3(-m_iSize, -m_iSize, -m_iSize),1.f, 1.f);
	m_Vertex[32].Init(Vector3(m_iSize, -m_iSize, -m_iSize),	5.f/6, 1.f);
	m_Vertex[33] = m_Vertex[30];
	m_Vertex[34].Init(Vector3(-m_iSize, m_iSize, -m_iSize),	1.f, 0.f);
	m_Vertex[35] = m_Vertex[31];
}


//----------------------------------------------------------------------
BOOL Skybox::SetCamera(Camera *camera, int height)
{
	if (!camera)
	{
		return FALSE;
	}

	m_pCamera = camera;
	m_iOffsetFromGround = height;

	return TRUE;
}


//----------------------------------------------------------------------
HRESULT Skybox::Render(const Camera &camera)
{
	if (!IsVisible())
	{
		return E_FAIL;
	}
	else
	{
		RenderQueue::GetSingleton()->PushToSkyboxRQ(this);
	}

	return S_OK;
}


//----------------------------------------------------------------------
HRESULT Skybox::Render()
{
	m_Material.SetFromMaterial();

	Vector3 p = m_pCamera->GetPosition();
	p += (m_iOffsetFromGround - m_iSize)*Vector3::Y_AXIS;

	MoveTo(p);

	GraphicLayer::GetSingleton()->SetFVF(CE_NLVERTEX::FVF);
	GraphicLayer::GetSingleton()->SetWorldMatrix(GetTransformMatrix());

	return GraphicLayer::GetSingleton()->DrawPrimitiveUp(D3DPT_TRIANGLELIST, 12, m_Vertex, sizeof(CE_NLVERTEX));
}